<template>
    <a-form :model="form" ref="formRef" :rules="formRules" :label-col="{ span: 6 }" :wrapper-col="{ span: 24 }">
        <a-row type="flex" justify="center" align="top">
            <a-col :span="12">
                <a-form-item :label="$t('upperComputer.user.userAccount')" name="account"
                    :labelCol="{ style: 'width: 100px' }">
                    <a-input v-model:value="form.account" :maxlength="50" :disabled="id != 0" />
                </a-form-item>
                <a-form-item :label="$t('upperComputer.user.userName')" name="displayName"
                    :labelCol="{ style: 'width: 100px' }">
                    <a-input v-model:value="form.displayName" :maxlength="50" />
                </a-form-item>
                <a-form-item :label="$t('upperComputer.user.sex')" name="sex" :labelCol="{ style: 'width: 100px' }">
                    <a-select v-model:value="form.sex">
                        <a-select-option v-for="item in genders" :key="item.value" :value="item.value">
                            {{ item.label }}
                        </a-select-option>
                    </a-select>
                </a-form-item>
            </a-col>
            <a-col :span="12">
                <a-form-item :label="$t('upperComputer.user.photo')" name="photo"
                    :labelCol="{ style: 'width: 100px;text-align: center;' }">
                    <a-tooltip placement="topLeft">
                        <template #title>
                            <span>
                                {{ $t("upperComputer.user.required.capacity") }}<br />{{
                                    $t("upperComputer.user.required.onlyJpeg")
                                }}
                            </span>
                        </template>
                        <a-upload name="file" list-type="picture-card" class="avatar-uploader" :show-upload-list="false"
                            action :before-upload="beforeUpload" accept="image/jpeg">
                            <img v-if="headerLogo" :src="headerLogo" alt="avatar" style="height: 80px; width: 100%;" />
                            <div v-else>
                                <loading-outlined v-if="spinning" />
                                <plus-outlined v-else />
                            </div>
                        </a-upload>
                    </a-tooltip>
                    <a-button v-if="headerLogo" type="primary" @click="deletePhoto" size="small">{{
                        $t("upperComputer.user.deletePhoto") }}</a-button>
                </a-form-item>
            </a-col>
        </a-row>
        <a-row>
            <a-col :span="24">
                <a-form-item :label="$t('upperComputer.user.description')" name="description"
                    :labelCol="{ style: 'width: 100px' }">
                    <a-textarea v-model:value="form.description" :auto-size="{ minRows: 3, maxRows: 5 }" :maxlength="255"
                        showCount style="width: 400px" />
                </a-form-item>
                <a-form-item :label="$t('upperComputer.user.role')" name="baseRoleUser"
                    :labelCol="{ style: 'width: 100px' }">
                    <a-table rowKey="id" :data-source="form.baseRoleUser" :pagination="false" bordered
                        style="width: 400px; height: 280px; overflow: auto;">
                        <a-table-column data-index="index" :title="$t('upperComputer.user.id')" align="center" ellipsis>
                            <template #default="item">
                                <span>{{
                                    item.index +
                                    1 /** 详细说明看columns的slots，在下边。index跟自己定义的要一致。item代表着行数据集合。 */
                                }}</span>
                            </template>
                        </a-table-column>
                        <a-table-column data-index="roleCode" :title="$t('upperComputer.user.roleCode')" align="center"
                            ellipsis />
                        <a-table-column data-index="roleName" :title="$t('upperComputer.user.roleName')" align="center"
                            ellipsis />
                        <a-table-column data-index="operation" align="center">
                            <template #title><a @click="addRoleUser">{{
                                $t("menuButton.post")
                            }}</a></template>
                            <template #default="{ record }">
                                <div class="editable-row-operations">
                                    <span>
                                        <a @click="editRoleUser(record)">
                                            {{ $t("menuButton.put") }} </a>&nbsp;
                                        <a-popconfirm v-if="form.baseRoleUser.length" :title="$t('common.deleteIt')"
                                            :okText="$t('common.ok')" :cancelText="$t('common.cancel')"
                                            @confirm="onDelete(record.id)">
                                            <a>{{ $t("menuButton.delete") }}</a>
                                        </a-popconfirm>
                                    </span>
                                </div>
                            </template>
                        </a-table-column>
                    </a-table>
                </a-form-item>
            </a-col>
        </a-row>
    </a-form>

    <a-modal :title="$t('upperComputer.user.giveRole')" centered :visible="secondFormVisible" :confirm-loading="spinning"
        :maskClosable="false" @ok="handleRoleOk" @cancel="secondFormVisible = false" width="400px">
        <a-form :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }">
            <a-form-item :label="$t('upperComputer.user.role')" name="role" :labelCol="{ style: 'width: 100px' }">
                <a-select v-model:value="currentRoleCode" @change="handleRoleChange" :placeholder="$t('common.select')"
                    optionFilterProp="label" show-search>
                    <a-select-option v-for="item in roles" :key="item.id" :value="item.code" :label="item.displayName">
                        {{ item.displayName }}
                    </a-select-option>
                </a-select>
            </a-form-item>
        </a-form>
    </a-modal>
</template>

<script setup lang='ts'>
import i18n from '@/i18n';
import url from '@/utils/axios/url';
import { message, type FormInstance } from 'ant-design-vue';
import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue';
import { type Ref, ref, onMounted } from 'vue';
import type { Rule } from 'ant-design-vue/lib/form';
import { UserDto } from '@/models/user';
import { getRoleListApi, getUserApi, postUserApi, putDeletePhotoApi, putUserApi } from '@/services/user';
import { confirm } from '@/utils';
import type { RoleResultDto } from '@/models/role';
import { RoleUserDto } from '@/models/role-user';

const props = defineProps<{ id: number }>();
defineExpose({ ok });

const headerLogo: Ref<string> = ref<string>('');
const spinning: Ref<boolean> = ref<boolean>(false);
const roles: Ref<Array<RoleResultDto>> = ref<Array<RoleResultDto>>(new Array<RoleResultDto>);
const currentRoleUser: Ref<RoleUserDto | undefined> = ref<RoleUserDto | undefined>();
const currentRoleCode: Ref<string | undefined> = ref<string | undefined>();
const currentRole: Ref<RoleResultDto | undefined> = ref<RoleResultDto | undefined>();
const secondFormVisible: Ref<boolean> = ref<boolean>(false);

const form: Ref<UserDto> = ref<UserDto>(new UserDto);
const formRef: Ref<FormInstance | undefined> = ref<FormInstance>();
const genders: Array<any> = [
    {
        value: 0,
        label: i18n.global.t('upperComputer.user.sex0') //未知
    },
    {
        value: 1,
        label: i18n.global.t('upperComputer.user.sex1') //男
    },
    {
        value: 2,
        label: i18n.global.t('upperComputer.user.sex2') //女
    }
];
const formRules: Record<string, Rule[]> = {
    account: [
        { required: true, trigger: 'blur', validator: checkAccount }
    ],
    displayName: [
        {
            required: true,
            message: i18n.global.t('upperComputer.user.required.userName'),
            trigger: 'blur'
        },
        {
            max: 50,
            message: i18n.global.t('upperComputer.user.required.fifty'),
            trigger: 'blur'
        }
    ],
    description: [
        {
            max: 255,
            message: i18n.global.t('upperComputer.user.required.twoHundredAndFifty'),
            trigger: 'blur',
        }
    ]
};

function checkAccount(rule: Rule, value: string, callback: Function): Promise<void> {
    const reg: RegExp = /^[a-zA-Z]{1,50}$/;
    if (reg.test(value)) {
        return Promise.resolve();
    }
    return Promise.reject(i18n.global.t('upperComputer.user.required.capital'));
}

onMounted(() => {
    getForm();
    searchRoles();
})

/**
 * 上传图片校验
 * @param file 
 */
function beforeUpload(file: any): boolean {
    const isJpg: boolean = file.type === 'image/jpeg';
    if (!isJpg) {
        message.error(i18n.global.t('upperComputer.user.required.jpeg'));
        return false;
    }
    const isLt2M: number | boolean = file.size ?? 0 / 1024 / 1024 < 2;
    if (!isLt2M) {
        message.error(i18n.global.t('upperComputer.user.required.imageSize'));
        return false;
    }

    form.value.file = file;
    headerLogo.value = URL.createObjectURL(file);
    return false;
}

/**
 * 删除头像
 */
async function deletePhoto(): Promise<void> {
    if (!form.value.file) {
        if (await confirm(i18n.global.t('common.prompt').toString(), i18n.global.t('common.deleteIt').toString())) {
            try {
                spinning.value = true;
                await putDeletePhotoApi(form.value);
                form.value.file = undefined;
                form.value.photo = headerLogo.value = '';
                message.success(i18n.global.t('upperComputer.user.required.photoSuccess'));
            } catch (error) {
            } finally {
                spinning.value = false;
            }
        }
    } else {
        form.value.file = undefined;
        headerLogo.value =
            form.value.photo === ''
                ? ''
                : url.imgGroup + form.value.photo;
    }
}

async function getForm(): Promise<void> {
    if (!props.id) {
        return;
    }
    form.value = await getUserApi(props.id);
    if (form.value.photo) {
        headerLogo.value = url.imgGroup + form.value.photo;
    } else {
        headerLogo.value = '';
    }
}

async function ok(): Promise<boolean> {
    try {
        await formRef.value?.validate();
        if (props.id) {
            await putUserApi(form.value);
        } else {
            await postUserApi(form.value);
        }
        message.success(i18n.global.t('common.' + (props.id ? 'editSuccess' : 'addSuccess')));
        return true;
    } catch {
        return false;
    }
}

async function searchRoles(): Promise<void> {
    roles.value = await getRoleListApi();
}

function addRoleUser(): void {
    currentRoleUser.value = undefined;
    currentRoleCode.value = undefined; //必须为null，哪怕为""，下拉框也不显示“请选择”
    currentRole.value = undefined;
    secondFormVisible.value = true;
}

function editRoleUser(row: RoleUserDto): void {
    currentRoleUser.value = row;
    currentRoleCode.value = row.roleCode;
    getCurrentRole(row.roleCode);
    secondFormVisible.value = true;
}

function handleRoleChange(val: string, option: any): void {
    getCurrentRole(val);
}

function getCurrentRole(val: string): void {
    for (let i: number = 0; i < roles.value.length; ++i) {
        const role: RoleResultDto = roles.value[i];
        if (role.code === val) {
            //赋值
            currentRole.value = role;
            currentRoleCode.value = val;
            break;
        }
    }
}

/**
 * 确定添加/编辑角色
 */
function handleRoleOk(): void {
    if (!currentRole.value) {
        message.warning(i18n.global.t('upperComputer.user.required.roleOne'));
        return;
    }
    let hasRoleCode: boolean = false;
    for (let i: number = 0; i < form.value.baseRoleUser.length; ++i) {
        if (form.value.baseRoleUser[i].roleCode === currentRole.value?.code) {
            hasRoleCode = true;
            break;
        }
    }
    if (hasRoleCode && currentRoleUser.value?.roleCode !== currentRoleCode.value) {
        message.warning(i18n.global.t('upperComputer.user.required.exists'));
        return;
    }
    if (currentRoleUser.value) {
        currentRoleUser.value.roleCode = currentRole.value?.code ?? '';
        currentRoleUser.value.roleName = currentRole.value?.displayName ?? '';
    } else {
        const roleUser: RoleUserDto = new RoleUserDto;
        roleUser.id = currentRole.value?.id ?? 0;
        roleUser.account = form.value.account;
        roleUser.roleCode = currentRole.value?.code ?? '';
        roleUser.roleName = currentRole.value?.displayName ?? '';
        form.value.baseRoleUser.push(roleUser);
    }
    secondFormVisible.value = false;
}

//删除
function onDelete(id: number): void {
    const dataSource: Array<RoleUserDto> = [...form.value.baseRoleUser];
    form.value.baseRoleUser = dataSource.filter(item => item.id !== id);
}
</script>

